package cn.demoncat.util.qcc;

import cn.demoncat.util.exception.BizErrorRuntimeException;
import cn.demoncat.util.exception.BizRuntimeException;
import cn.demoncat.util.http.HttpUtil;
import cn.demoncat.util.http.entity.HttpRequest;
import cn.demoncat.util.lang.IntegerUtil;
import cn.demoncat.util.lang.ObjectUtil;
import cn.demoncat.util.lang.OptionalUtil;
import cn.demoncat.util.lang.ParamEmptyUtil;
import cn.demoncat.util.lang.entity.MapSs;
import cn.demoncat.util.lang.entity.Pager;
import cn.demoncat.util.lang.entity.Result;
import cn.demoncat.util.qcc.config.QccProperties;
import cn.demoncat.util.qcc.constant.QccConstant;
import cn.demoncat.util.sec.Md5Util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 企查查工具
 *
 * @author 延晓磊
 * @since 2021年09月17日
 *
 * @see <a href="https://openapi.qcc.com/dataApi">接口文档</a>
 */
@Component
public class QccUtil {

    @Resource
    private QccProperties qccProperties;

    private static final Logger LOG = LoggerFactory.getLogger(QccUtil.class);

    /**
     * 综合查询
     *
     * @param api       接口名称：QccConstant.Api
     * @param param     接口参数：企业名称、统一信用代码；列表数据的id
     * @param pageNum   页码：分页参数，默认1
     * @param pageSize  页长：分页参数，最大20，默认为接口的最大限制
     * @return
     *
     * @author 延晓磊
     * @since 2021年11月23日
     */
    public Result query(String api, String param, Integer pageNum, Integer pageSize){
        // 参数校验
        ParamEmptyUtil.checkBlank(api, param);
        // 查询接口
        switch (QccConstant.Api.valueOf(api)) {
            case ECISearchWide:
                // 企业工商信息查询-多维度查询：企业名
                return Result.successList(eciSearchWide(param));
            case ECIGetBasicDetailsByName:
                // 企业工商信息查询-详情：企业全名，统一信用号码
                return Result.success(eciGetBasicDetailsByName(param));
            case ECIInfoVerify:
                // 企业工商信息详情：企业全名，统一信用号码
                return Result.success(eciInfoVerify(param));
            case ARSummary:
                // 企业年报信息-概况：企业全名，统一信用号码
                return Result.successList(arSummary(param));
            case AR:
                // 企业年报信息：企业全名，统一信用号码
                return Result.successList(ar(param));
            case ECIImage:
                // 工商快照：企业全名，统一信用号码
                return Result.successStr(eciImage(param));
            case CompanyNews:
                // 新闻舆情：企业全名，统一信用号码
                return Result.success(companyNews(param, pageNum, pageSize));
            case CompanyNewsDetail:
                // 新闻舆情-详情：列表项id
                return Result.success(companyNewsDetail(param));
            case JudicialSaleCheck:
                // 司法拍卖核查：企业全名，统一信用号码
                return Result.success(judicialSaleCheck(param, pageNum, pageSize));
            case JudicialSaleCheckDetail:
                // 司法拍卖核查-详情：列表项id
                return Result.success(judicialSaleCheckDetail(param));
            case SeriousIllegalCheck:
                // 严重违法核查：企业全名，统一信用号码
                return Result.successList(seriousIllegalCheck(param));
            case TaxOweNoticeCheck:
                // 欠税公告核查：企业全名，统一信用号码
                return Result.success(taxOweNoticeCheck(param, pageNum, pageSize));
            case TaxOweNoticeCheckDetail:
                // 欠税公告核查-详情：列表项id
                return Result.success(taxOweNoticeCheckDetail(param));
            case TaxIllegalCheck:
                // 税收违法核查：企业全名，统一信用号码
                return Result.success(taxIllegalCheck(param, pageNum, pageSize));
            case TaxIllegalCheckDetail:
                // 税收违法核查-详情：列表项id
                return Result.success(taxIllegalCheckDetail(param));
            case AdminPenaltyCheck:
                // 行政处罚核查：企业全名，统一信用号码
                return Result.success(adminPenaltyCheck(param, pageNum, pageSize));
            case ChattelMortgageCheck:
                // 动产抵押核查：企业全名，统一信用号码
                return Result.success(chattelMortgageCheck(param, pageNum, pageSize));
            case ZhixingCheck:
                // 被执行人核查：企业全名，统一信用号码
                return Result.success(zhixingCheck(param, pageNum, pageSize));
            case ZhixingCheckDetail:
                // 被执行人核查-详情：列表项id
                return Result.success(zhixingCheckDetail(param));
            case ShixinCheck:
                // 失信核查：企业全名，统一信用号码
                return Result.success(shixinCheck(param, pageNum, pageSize));
            case ShixinCheckDetail:
                // 失信核查-详情：列表项id
                return Result.success(shixinCheckDetail(param));
            case ExceptionCheck:
                // 经营异常核查：企业全名，统一信用号码
                return Result.successList(exceptionCheck(param));
            case ECIInfoOverview:
                // 企业工商风险扫描：企业全名，统一信用号码
                return Result.success(eciInfoOverview(param));
            case EnvPunishmentCheck:
                // 环保处罚核查：企业全名，统一信用号码
                return Result.success(envPunishmentCheck(param, pageNum, pageSize));
            case EnvPunishmentCheckDetail:
                // 环保处罚核查-详情：列表项id
                return Result.success(envPunishmentCheckDetail(param));
            case Patent:
                // 专利查询：企业全名，统一信用号码
                return Result.success(patent(param, pageNum, pageSize));
            case PatentDetail:
                // 专利查询-详情：列表项id
                return Result.success(patentDetail(param));
            case TM:
                // 商标查询：企业全名
                return Result.success(tm(param, pageNum, pageSize));
            case TMDetail:
                // 商标查询-详情：列表项id
                return Result.success(tmDetail(param));
            case ECICertification:
                // 企业证书查询：企业全名
                return Result.success(eciCertification(param, pageNum, pageSize));
            case ECICertificationDetail:
                // 企业证书查询-详情：列表项id
                return Result.success(eciCertificationDetail(param));
            case WebSite:
                // 备案网站查询：企业全名，统一信用号码
                return Result.success(webSite(param, pageNum, pageSize));
            case ADSTLicense:
                // 行政许可-其它：企业全名，统一信用号码
                return Result.success(adstLicense(param, pageNum, pageSize));
            case ADSTLicenseGs:
                // 行政许可-工商：企业全名，统一信用号码
                return Result.success(adstLicenseGs(param, pageNum, pageSize));
            case ADSTLicenseDetail:
                // 行政许可-详情：列表项id
                return Result.success(adstLicenseDetail(param));
            default:
                return Result.error("不支持该查询");
        }
    }

    /**
     * 企业三要素核验
     *
     * @param code    统一社会信用代码
     * @param name   企业名称
     * @param legalName   法定代表人名称
     *
     * @return
     */
    public Result eciThreeElVerify(String code, String name, String legalName){
        JSONObject result = toResult(doGet(QccConstant.Api.ECIThreeElVerify, MapSs.getInstance("creditCode", code, "companyName", name, "operName", legalName)));
        switch (result.getIntValue("VerifyResult")) {
            case 1:
                return Result.SUCCESS;
            case 0:
                return Result.error("统一社会信用代码有误");
            case 2:
                return Result.error("企业名称不一致");
            case 3:
                return Result.error("法人名称不一致");
            default:
                // 不存在的结果
                return Result.error("未知错误");
        }
    }

    /**
     * 企业工商信息详情
     *
     * @param key   企业名称、统一社会信用代码
     *
     * @return 企业信息
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=76168a3e-b52f-4d69-bed2-0e4d8ea0d38c">接口文档</>
     */
    public JSONObject eciInfoVerify(String key){
        return toResult(doGet(QccConstant.Api.ECIInfoVerify, MapSs.getInstance("searchKey", key)));
    }

    /**
     * 企业工商信息查询-多维度查询
     *
     * @param key   搜索关键字
     * @return [企业简信，20条]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=f738e318-62b5-11e7-bbdd-00155d0ab207">接口文档</>
     */
    public JSONArray eciSearchWide(String key){
        return toResultList(doGet(QccConstant.Api.ECISearchWide, MapSs.getInstance("keyword", key, "pageSize", "20")));
    }

    /**
     * 企业工商信息查询（比 ECIInfoVerify 信息简单、收费低）
     *
     * @param key   企业名称、统一社会信用代码
     *
     * @return 企业信息
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=f738e318-62b5-11e7-bbdd-00155d0ab207">接口文档</>
     */
    public JSONObject eciGetBasicDetailsByName(String key){
        return toResult(doGet(QccConstant.Api.ECIGetBasicDetailsByName, MapSs.getInstance("keyword", key)));
    }

    /**
     * 司法拍卖核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=3c740d13-14bd-4bdd-8739-d336632244c8">接口文档</>
     */
    public Pager<Object> judicialSaleCheck(String key, Integer pageNum, Integer pageSize){
        return toResultDataPager(doGet(QccConstant.Api.JudicialSaleCheck, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 司法拍卖核查-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=3c740d13-14bd-4bdd-8739-d336632244c8">接口文档</>
     */
    public JSONObject judicialSaleCheckDetail(String id){
        return toResult(doGet(QccConstant.Api.JudicialSaleCheckDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 环保处罚核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=adc2f873-dd6f-4f44-8b83-51f73b60375c">接口文档</>
     */
    public Pager<Object> envPunishmentCheck(String key, Integer pageNum, Integer pageSize){
        return toResultDataPager(doGet(QccConstant.Api.EnvPunishmentCheck, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 环保处罚核查-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=adc2f873-dd6f-4f44-8b83-51f73b60375c">接口文档</>
     */
    public JSONObject envPunishmentCheckDetail(String id){
        return toResult(doGet(QccConstant.Api.EnvPunishmentCheckDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 严重违法核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @return JsonArray
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=046923c0-d0b8-4cf8-9562-ed1ec4b6665b">接口文档</>
     */
    public JSONArray seriousIllegalCheck(String key){
        return toResultDataList(doGet(QccConstant.Api.SeriousIllegalCheck, MapSs.getInstance("searchKey", key)));
    }

    /**
     * 欠税公告核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=8851330d-ae2b-4236-8ea8-0507e22c029d">接口文档</>
     */
    public Pager<Object> taxOweNoticeCheck(String key, Integer pageNum, Integer pageSize){
        return toResultDataPager(doGet(QccConstant.Api.TaxOweNoticeCheck, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 欠税公告核查-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=8851330d-ae2b-4236-8ea8-0507e22c029d">接口文档</>
     */
    public JSONObject taxOweNoticeCheckDetail(String id){
        return toResult(doGet(QccConstant.Api.TaxOweNoticeCheckDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 税收违法核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=0e3d345e-130c-4d77-956a-11defeb3cb9d">接口文档</>
     */
    public Pager<Object> taxIllegalCheck(String key, Integer pageNum, Integer pageSize){
        return toResultDataPager(doGet(QccConstant.Api.TaxIllegalCheck, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 税收违法核查-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=0e3d345e-130c-4d77-956a-11defeb3cb9d">接口文档</>
     */
    public JSONObject taxIllegalCheckDetail(String id){
        return toResult(doGet(QccConstant.Api.TaxIllegalCheckDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 行政处罚核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum 页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=8c25a4f0-c92b-4b8c-9cda-f81abe747c2b">接口文档</>
     */
    public Pager<Object> adminPenaltyCheck(String key, Integer pageNum, Integer pageSize){
        return toResultDataPager(doGet(QccConstant.Api.AdminPenaltyCheck, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 动产抵押核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=d983dc15-3b66-483f-bd1f-4905d6717a4a">接口文档</>
     */
    public Pager<Object> chattelMortgageCheck(String key, Integer pageNum, Integer pageSize){
        return toResultDataPager(doGet(QccConstant.Api.ChattelMortgageCheck, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 被执行人核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=70e0747a-e6a1-4de5-83ff-c47904182ca2">接口文档</>
     */
    public Pager<Object> zhixingCheck(String key, Integer pageNum, Integer pageSize){
        return toResultDataPager(doGet(QccConstant.Api.ZhixingCheck, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 被执行人核查-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=70e0747a-e6a1-4de5-83ff-c47904182ca2">接口文档</>
     */
    public JSONObject zhixingCheckDetail(String id){
        return toResult(doGet(QccConstant.Api.ZhixingCheckDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 失信核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=f390019d-8695-4170-84ef-73e8971fbe91">接口文档</>
     */
    public Pager<Object> shixinCheck(String key, Integer pageNum, Integer pageSize){
        return toResultDataPager(doGet(QccConstant.Api.ShixinCheck, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 失信核查-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=f390019d-8695-4170-84ef-73e8971fbe91">接口文档</>
     */
    public JSONObject shixinCheckDetail(String id){
        return toResult(doGet(QccConstant.Api.ShixinCheckDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 专利查询-公司专利多重查询
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为50，最大不超过50
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=a32277f9-98c4-4e96-96f1-f7ed1a734701">接口文档</>
     */
    public Pager<Object> patent(String key, Integer pageNum, Integer pageSize){
        return toResultPager(doGet(QccConstant.Api.Patent, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 50))));
    }

    /**
     * 专利查询-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=a32277f9-98c4-4e96-96f1-f7ed1a734701">接口文档</>
     */
    public JSONObject patentDetail(String id){
        return toResult(doGet(QccConstant.Api.PatentDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 商标查询-根据申请人查询商标列表
     *
     * @param key       公司名
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为50，最大不超过50
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=50bd3328-013c-11e6-896b-00155d0ab207">接口文档</>
     */
    public Pager<Object> tm(String key, Integer pageNum, Integer pageSize){
        return toResultPager(doGet(QccConstant.Api.TM, MapSs.getInstance("keyword", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 50))));
    }

    /**
     * 商标查询-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=50bd3328-013c-11e6-896b-00155d0ab207">接口文档</>
     */
    public JSONObject tmDetail(String id){
        return toResult(doGet(QccConstant.Api.TMDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 新闻舆情
     *
     * @param key       公司名
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为50，最大不超过50
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=13d8745e-e2f2-4f88-b693-bac52dc00759">接口文档</>
     */
    public Pager<Object> companyNews(String key, Integer pageNum, Integer pageSize){
        return toResultPager(doGet(QccConstant.Api.CompanyNews, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 50))));
    }

    /**
     * 新闻舆情-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=13d8745e-e2f2-4f88-b693-bac52dc00759">接口文档</>
     */
    public JSONObject companyNewsDetail(String id){
        return toResult(doGet(QccConstant.Api.CompanyNewsDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 行政许可列表-工商
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为50，最大不超过50
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=ed0b4c70-5126-4b93-8018-840b5ab9b27d">接口文档</>
     */
    public Pager<Object> adstLicenseGs(String key, Integer pageNum, Integer pageSize){
        return toResultPager(doGet(QccConstant.Api.ADSTLicenseGs, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 50))));
    }

    /**
     * 行政许可列表-其它
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为50，最大不超过50
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=ed0b4c70-5126-4b93-8018-840b5ab9b27d">接口文档</>
     */
    public Pager<Object> adstLicense(String key, Integer pageNum, Integer pageSize){
        return toResultPager(doGet(QccConstant.Api.ADSTLicense, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 50))));
    }

    /**
     * 行政许可-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=ed0b4c70-5126-4b93-8018-840b5ab9b27d">接口文档</>
     */
    public JSONObject adstLicenseDetail(String id){
        return toResult(doGet(QccConstant.Api.ADSTLicenseDetail, MapSs.getInstance("id", id)));
    }

    /**
     * 企业证书查询
     *
     * @param key       公司名
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=82514ffc-475b-11e6-afda-00155d0ab207">接口文档</>
     */
    public Pager<Object> eciCertification(String key, Integer pageNum, Integer pageSize){
        return toResultPager(doGet(QccConstant.Api.ECICertification, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 企业证书查询-详情
     *
     * @param id       列表项
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=82514ffc-475b-11e6-afda-00155d0ab207">接口文档</>
     */
    public JSONObject eciCertificationDetail(String id){
        return toResult(doGet(QccConstant.Api.ECICertificationDetail, MapSs.getInstance("certId", id)));
    }

    /**
     * 企业年报信息
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=031edf39-013c-11e6-896b-00155d0ab207">接口文档</>
     */
    public JSONArray ar(String key){
        return toResultList(doGet(QccConstant.Api.AR, MapSs.getInstance("keyNo", key)));
    }

    /**
     * 企业年报信息-概况
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @return
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=031edf39-013c-11e6-896b-00155d0ab207">接口文档</>
     */
    public JSONArray arSummary(String key){
        return toResultList(doGet(QccConstant.Api.ARSummary, MapSs.getInstance("keyNo", key)));
    }

    /**
     * 经营异常核查
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @return JsonArray
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=5c28b452-cfe2-4e0f-bb05-b15a0f976371">接口文档</>
     */
    public JSONArray exceptionCheck(String key){
        return toResultDataList(doGet(QccConstant.Api.ExceptionCheck, MapSs.getInstance("searchKey", key)));
    }

    /**
     * 企业工商风险扫描(多维度核查信息)
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @return 企业工商信息（工商照面、股东信息、主要人员、分支机构、变更信息、行业分类等），企业风险信息（行政处罚、经营异常、失信被执行人、被执行人、动产抵押、清算、股权出质、抽查检查、纳税信用）
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=d2d4ed4a-c9f9-4150-b2a1-298e9a2778c4">接口文档</>
     */
    public JSONObject eciInfoOverview(String key){
        return toResult(doGet(QccConstant.Api.ECIInfoOverview, MapSs.getInstance("searchKey", key)));
    }

    /**
     * 备案网站查询
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @param pageNum   页码，默认第一页
     * @param pageSize  每页条数，默认为20，最大不超过20
     * @return Pager[JsonArray]
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=c33cce18-5cb6-411d-95b9-0c79edfe964b">接口文档</>
     */
    public Pager<Object> webSite(String key, Integer pageNum, Integer pageSize){
        return toResultPager(doGet(QccConstant.Api.WebSite, MapSs.getInstance("searchKey", key, "pageIndex", IntegerUtil.toString(pageNum, 1), "pageSize", IntegerUtil.toString(pageSize, 20))));
    }

    /**
     * 工商快照
     *
     * @param key       公司名、注册号、统一社会信用代码
     * @return 图片地址
     *
     * @see <a href="https://openapi.qcc.com/dataApi/dataDetail?apiId=cea55e1a-7283-4846-894b-1e6cebc8b9e7">接口文档</>
     */
    public String eciImage(String key){
        return doGet(QccConstant.Api.ECIImage, MapSs.getInstance("keyWord", key)).getString("Result");
    }


    /**
     * GET请求
     *
     * @param api
     * @param param
     *
     * @return
     *
     * @throws BizErrorRuntimeException 请求失败
     * @throws BizRuntimeException 响应错误
     */
    private JSONObject doGet(QccConstant.Api api, MapSs param){
        // 请求时间
        String time =  String.valueOf(System.currentTimeMillis()/1000);
        // 发起请求
        JSONObject json;
        try {
            json = HttpUtil.request(HttpRequest.get(QccConstant.URL + api.getUrl())
                    .addHeader(MapSs.getInstance(
                            "Token", Md5Util.digest(qccProperties.getKey() + time + qccProperties.getSecret()).toUpperCase(),
                            "Timespan", time
                    ))
                    .addParam(param.add("key", qccProperties.getKey()))).asBean();
        }catch (Exception e){
           throw new BizErrorRuntimeException("请求企查查失败：api = " + api.getName(), e);
        }
        // 读取响应
        if ("200".equals(json.getString("Status"))) {
            LOG.info("请求企查查成功：api = {}, order = {}", api.getName(), json.getString("OrderNumber"));
            return json;
        }else{
            String message = json.getString("Message");
            String status = json.getString("Status");
            LOG.warn("请求企查查接口失败：api = {}, status = {}, message = {}, order = {}", api.getName(), status , message, json.getString("OrderNumber"));
            switch (status) {
                case "201":
                    // 查无结果
                    return new JSONObject();
                default:
                    throw new BizRuntimeException("请求企查查出错：" + message);
            }
        }
    }

    /**
     * 将结果转换为Object
     *
     * @param result    响应结果：{Result:{}}
     * @return
     */
    private static JSONObject toResult(JSONObject result){
        return result.getJSONObject("Result");
    }

    /**
     * 将结果转换为List
     *
     * @param result    响应结果：{Result:[]}
     * @return [Result.Data]
     */
    private static JSONArray toResultList(JSONObject result){
        return ObjectUtil.toDefault(result.getJSONArray("Result"), new JSONArray());
    }

    /**
     * 将结果转换为Pager
     *
     * @param result    响应结果：{Paging：{}, Result:[]}
     * @return
     */
    private static Pager<Object> toResultPager(JSONObject result){
        JSONObject paging = result.getJSONObject("Paging");
        if (paging != null) {
            return new Pager<>(paging.getInteger("PageIndex"), paging.getInteger("PageSize"), paging.getLong("TotalRecords")).setList(toResultList(result));
        }
        return Pager.EMPTY_PAGER;
    }

    /**
     * 将结果转换为List
     *
     * @param result    响应结果：{Result:{Data:[]}}
     * @return [Result.Data]
     */
    private static JSONArray toResultDataList(JSONObject result){
        return ObjectUtil.toDefault(OptionalUtil.get(result.getJSONObject("Result"), o -> o.getJSONArray("Data")), new JSONArray());
    }

    /**
     * 将结果转换为Pager
     *
     * @param result    响应结果：{Paging：{}, Result:{Data:[]}}
     * @return
     */
    private static Pager<Object> toResultDataPager(JSONObject result){
        JSONObject paging = result.getJSONObject("Paging");
        if (paging != null) {
            return new Pager<>(paging.getInteger("PageIndex"), paging.getInteger("PageSize"), paging.getLong("TotalRecords")).setList(toResultDataList(result));
        }
        return Pager.EMPTY_PAGER;
    }

}
